package cn.com.yto56.coresystem.business.msg.mc.biz.impl;

import cn.com.yto56.coresystem.business.msg.mc.biz.IClientInfoBiz;
import cn.com.yto56.coresystem.business.msg.mc.util.ChannelManagerBean;
import cn.com.yto56.coresystem.business.msg.mc.util.MsgResult;
import cn.com.yto56.coresystem.common.msg.util.io.AppConfigurationUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Vector;

/**
 * Created by wangrui on 2017/4/13.
 */
@Service
public class MsgChannelManager {
    //最大连接数
    private static int connectionPool = AppConfigurationUtil.getPropertyValue("msg.mc.connectionPool")==null?3000:Integer.valueOf(AppConfigurationUtil.getPropertyValue("msg.mc.connectionPool"));
    //临时client存活时间单位 毫秒
    private static int tempTime = AppConfigurationUtil.getPropertyValue("msg.mc.tempTime")==null?30000:Integer.valueOf(AppConfigurationUtil.getPropertyValue("msg.mc.connectionPool"));;
    //管理channel
    public static List<ChannelManagerBean> channelManagerBeanList = new Vector<ChannelManagerBean>();
    //静态变量
    @Autowired
    private IClientInfoBiz clientInfoServiceImpl;


    /**
     * 添加channel
     *
     * @param clientId
     * @param channel
     */
    public synchronized void addChannel(String clientId, Channel channel) {
        if (channelManagerBeanList.size() >= connectionPool) {
            sendPrompt(channel, "已超过服务器连接上限！");
        } else {
            //如果存在相同clientId则关闭channel
            if (channelManagerBeanList != null) {
                for (int i = 0; i < channelManagerBeanList.size(); i++) {
                    if (channelManagerBeanList.get(i).getClientId().equals(clientId)) {
                        sendPrompt(channelManagerBeanList.get(i).getChannel(), null);
                        channelManagerBeanList.remove(i);
                        break;
                    }
                }
            }

            //添加channel
            ChannelManagerBean channelManagerBean = new ChannelManagerBean();
            channelManagerBean.setClientId(clientId);
            channelManagerBean.setChannel(channel);
            channelManagerBean.setConnectionTime(new Date());
            channelManagerBeanList.add(channelManagerBean);

        }

    }

    /**
     * 更新channel
     *
     * @param channel
     */
    public synchronized void updateByChannel(String clientId, Channel channel) {
        if (channelManagerBeanList != null) {
            if (getChannelByClientId(clientId) != null) {
                sendPrompt(getChannelByClientId(clientId), null);
            }

            for (int i = 0; i < channelManagerBeanList.size(); i++) {
                if (channelManagerBeanList.get(i).getChannel() == channel) {
                    if (!clientId.equals(channelManagerBeanList.get(i).getClientId())) {
                        channelManagerBeanList.get(i).setClientId(clientId);
                        channelManagerBeanList.get(i).setLoginTime(new Date());
                        //修改数据库
                        String tempClientId = channelManagerBeanList.get(i).getClientId();
                        String[] tempParams = tempClientId.split("\\|");
                        String sysInfo_Id = tempParams[0];
                        String userId = tempParams[1];
                        String connectionTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(channelManagerBeanList.get(i).getConnectionTime());
                        String loginTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(channelManagerBeanList.get(i).getLoginTime());
                        clientInfoServiceImpl.addOrUpdateClientInfo(sysInfo_Id, userId, "1", connectionTime, loginTime, null, null);
                        break;
                    }
                }
            }
        }
    }

    /**
     * 更新client
     *
     * @param clientId
     * @param channel
     */
    public synchronized void updateByClientId(String clientId, Channel channel) {
        if (channelManagerBeanList != null) {
            for (int i = 0; i < channelManagerBeanList.size(); i++) {
                ChannelManagerBean channelManagerBean = channelManagerBeanList.get(i);
                String tempClientId = channelManagerBean.getClientId();
                if (tempClientId.equals(clientId)) {
                    sendPrompt(channelManagerBean.getChannel(), null);
                    channelManagerBean.setChannel(channel);
                    channelManagerBeanList.set(i, channelManagerBean);
                    break;
                }
            }
        }
    }


    /**
     * 获取channel
     *
     * @param clientId
     * @return
     */
    public synchronized Channel getChannelByClientId(String clientId) {
        if (channelManagerBeanList != null) {
            for (int i = 0; i < channelManagerBeanList.size(); i++) {
                if (channelManagerBeanList.get(i).getClientId().equals(clientId)) {
                    return channelManagerBeanList.get(i).getChannel();
                }
            }
        }
        return null;
    }

    /**
     * 移除channel
     *
     * @param channel
     */
    public synchronized String removeByChannel(Channel channel) {
        String result = "";
        if (channelManagerBeanList != null) {
            for (int i = 0; i < channelManagerBeanList.size(); i++) {
                if (channelManagerBeanList.get(i).getChannel() == channel) {
                    sendPrompt(channelManagerBeanList.get(i).getChannel(), "您已被服务器关闭连接");
                    result = channelManagerBeanList.get(i).getClientId();
                    channelManagerBeanList.remove(i);
                    if(!result.startsWith("mc_temp_")){
                        //修改数据库
                        String[] tempParams = result.split("\\|");
                        String sysInfo_Id = tempParams[0];
                        String userId = tempParams[1];
                        String unConnectionTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                        clientInfoServiceImpl.addOrUpdateClientInfo(sysInfo_Id, userId, "0", null, null, unConnectionTime, null);
                    }
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 通过Id去删除连接
     *
     * @param clientId
     * @return
     */
    public synchronized void removeByClientId(String clientId) {
        if (channelManagerBeanList != null) {
            for (int i = 0; i < channelManagerBeanList.size(); i++) {
                if (channelManagerBeanList.get(i).getClientId().equals(clientId)) {
                    sendPrompt(channelManagerBeanList.get(i).getChannel(), "您已被服务器关闭连接");
                    channelManagerBeanList.remove(i);
                    break;
                }
            }
        }
    }

    /**
     * 发送信息并关闭channel
     *
     * @param channel
     * @param msg
     */
    public synchronized void sendPrompt(Channel channel, String msg) {
        if (channel != null) {
            if (msg == null || "".equals(msg)) {
                msg = "您的账号已在另一个地方登陆,您已和服务器断开！";
            }
            MsgResult msgResult = new MsgResult();
            String responseJson = msgResult.getResponseJson("ytoMsgService.prompt", false, msg, null);
            try {
                ByteBuf buf = Unpooled.buffer(responseJson.getBytes("UTF-8").length);
                buf.writeBytes(responseJson.getBytes("UTF-8"));
                channel.writeAndFlush(buf);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            channel.close();
            channel = null;
        }

    }


    /**
     * 去掉超时未注册的channel
     *
     * @param currentDate 当前时间
     */
    public synchronized void removeTempChannel(Date currentDate) {
        if (channelManagerBeanList != null && channelManagerBeanList.size() > 0) {
            List<ChannelManagerBean> tempChannelManagerBeanList = channelManagerBeanList;
            for (int i = 0; i < tempChannelManagerBeanList.size(); i++) {
                if (tempChannelManagerBeanList.get(i).getClientId().startsWith("mc_temp_")
                        && (currentDate.getTime() - tempChannelManagerBeanList.get(i).getConnectionTime().getTime()) * 1000 > tempTime) {
                    sendPrompt(tempChannelManagerBeanList.get(i).getChannel(), "您长时间未注册，服务器已与您断开连接");
                    channelManagerBeanList.remove(tempChannelManagerBeanList.get(i));
                }
            }
        }
    }
}
